/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.api.adwords.starterkit.examples.enhancedads;

import java.util.Formatter;
import java.util.Locale;

/**
 * The Class Currency is responsible to format a Float value into the 
 * currency specified.
 * 
 * @author rodrigo.f.vale@gmail.com
 */
public class Currency {
  private String currencySign; 
  private String decimalSeparator;
  private String thousandsSeparator;
  
  /**
   * Instantiates a new currency. Not using standard Java
   * currency Class because it behavior is not compatible
   * with AdWords AdParam. 
   *
   * @param currencySign the currency sign
   * @param decimalSeparator the decimal separator
   * @param thousandsSeparator the thousands separator
   */
  public Currency(String currencySign, 
      String decimalSeparator, String thousandsSeparator) {
    this.currencySign = currencySign;
    this.decimalSeparator = decimalSeparator;
    this.thousandsSeparator = thousandsSeparator;
  }
  
  public boolean isCurrency(String value) {
    if (value == null) {
      return false;
    }
    
    String iCurrencySign = currencySign.replaceAll("([\\W])", "\\\\$0");
    
    String iThousandsSeparator 
        = thousandsSeparator.replaceAll("([\\W])", "\\\\$0");
    
    String iDecimalSeparator = decimalSeparator.replaceAll("([\\W])", "\\\\$0");
    
    String regexp = "\\s*" + iCurrencySign + "\\s*\\d+(" + iThousandsSeparator 
        + "\\d{3})?(" + iDecimalSeparator + "\\d+)?";

    return value.matches(regexp);
  }
  
  /**
   * Convert a monetary value in String format to Float
   *
   * @param price the monetary value. i.e US$1500.00
   * @return the float value. i.e 1500.00
   */
  public float toFloat(String price) {
    // string is a simple float value
    if (price.matches("([0-9]|\\.)+")) {
      return Float.parseFloat(price);
    } else {
      price = price.replaceAll("[^0123456789.,]", "");
      if (price.contains(".") && price.contains(",")) {
        if (decimalSeparator.equals(",")) {
          price = price.replace(".", "");
          price = price.replace(",", ".");
        } else if (decimalSeparator.equals(".")) {
          price = price.replace(",", "");
        }
      } else {
        if (price.contains(",")) {
          if (decimalSeparator.equals(".")) {
            price = price.replace(",", "");
          } else if (decimalSeparator.equals(",")) {
            price = price.replace(",", ".");
          }  
        } else if (price.contains(".")) {
          if (decimalSeparator.equals(",")) {
            price = price.replace(".", "");
          }
        }
      }
    }
    return Float.parseFloat(price);
  }
  
  /**
   * Convert a float value into a monetary value
   *
   * @param value the float value to be converted. i.e 1500.99
   * @return the monetary value in string format. i.e US$1500.99
   */
  public String toString(float value) {
    Formatter f = new Formatter();
    Locale l = Locale.US;
    
    if (decimalSeparator.equals(".") && thousandsSeparator.equals(",")) {
      l = Locale.US;
    } else if (decimalSeparator.equals(",") && thousandsSeparator.equals(".")) {
      l = Locale.ITALIAN;
    } else if (decimalSeparator.equals(" ") && thousandsSeparator.equals(",")) {
      l = Locale.FRANCE;
    } 
    
    // No decimal number, so we can create a small string
    if (Math.floor(value) == value) {
      return currencySign + f.format(l, "%,.0f", value).toString(); 
    }
    return currencySign + f.format(l, "%,.2f", value).toString();
  }
}